package com.navinfo.tripanalysis.common.arithmetic;

import com.navinfo.tripanalysis.common.arithmetic.annotation.Arithmetic;
import com.navinfo.tripanalysis.common.arithmetic.common.CommonData;
import com.navinfo.tripanalysis.common.arithmetic.common.DrivingData;
import com.navinfo.tripanalysis.common.arithmetic.common.OuterEventData;
import com.navinfo.tripanalysis.common.arithmetic.common.OuterStatisticData;
import com.navinfo.tripanalysis.common.arithmetic.custom.VarSharpAcceleration;
import com.navinfo.tripanalysis.common.arithmetic.custom.VarUreaLevel;
import com.navinfo.tripanalysis.common.arithmetic.enums.EventStatus;
import com.navinfo.tripanalysis.common.arithmetic.exception.RangeAssert;
import com.navinfo.tripanalysis.common.arithmetic.manager.AbstractArithmetic;
import com.navinfo.tripanalysis.common.config.ConfigMap;
import com.navinfo.tripanalysis.common.protocol.java.EventDataPb;
import com.navinfo.tripanalysis.common.util.ArithmeticUtils;

import java.util.Optional;

/**
 * 东风尿素异常算法<br/>
 * 依赖{@link Mileage}尿素异常算法<br/>
 * 输出：统计、事件<br/>
 * @author web
 */
@Arithmetic(name = "东风尿素异常算法")
public class UreaAbnormal_DF extends AbstractArithmetic<VarUreaLevel> {
    /**
     * 算法名称
     */
    private final String arithmeticName = "东风尿素液位异常";
    /**
     * 事件类型
     */
    private final EventDataPb.EventType eventType = EventDataPb.EventType.ureaAbnormal;

    /**
     * 加速度阀值,默认1.2m/s2
     */
    private  Long levelThreshold =  10L;




    @Override
    public void calculate() {
        logger.debug("{}算法开始...", arithmeticName);
        VarUreaLevel var = super.getObj();
        CommonData commonData = drivingData.getCommonData();
        levelThreshold = Optional.ofNullable(drivingData.getCommonData().getUreaAbnormalLevel()).orElse(10L);
        boolean isCurUreaAbnormal = false;
        //是否尿素液位异常：本次尿素液位 - 上次尿素液位 > |10|,2分钟之内,如果是开启event
       if ((drivingData.getCommonData().getUreaLevel()/100-drivingData.getCommonData().getLastUreaLevel()/100 >levelThreshold || drivingData.getCommonData().getLastUreaLevel() - drivingData.getCommonData().getUreaLevel() >levelThreshold)
               &&  drivingData.getCommonData().getGpsTime()-drivingData.getCommonData().getLastGpsTime()<120000 && !var.isPreAbnormalUrea() ){
           startEventData(eventType);
           var.setAbnormal_level(drivingData.getCommonData().getUreaLevel());
           var.setAbnormal_time(drivingData.getCommonData().getGpsTime());
           var.setLast_level(drivingData.getCommonData().getLastUreaLevel());
           var.setPreAbnormalUrea(true);
           OuterEventData eventData = drivingData.getEventData(eventType);
           //ExtendField05 存异常阈值
           if (eventData.getExtendField05()==null){
               eventData.setExtendField05(Double.valueOf(levelThreshold));
           }
           //ExtendField09 存在异常时间点
           if (eventData.getExtendField09()==null){
               eventData.setExtendField09(Optional.ofNullable(var.getAbnormal_time()).orElse(0L));
           }

           //ExtendField07 存放当前异常液位
           if (eventData.getExtendField07()==null) {
               eventData.setExtendField07(Optional.ofNullable(var.getAbnormal_level()).orElse(0.00));
           }
           //ExtendField08 存放上一个点异常液位
           if (eventData.getExtendField08()==null) {
               eventData.setExtendField08(Optional.ofNullable(var.getLast_level()).orElse(0.00));
           }
           return;
        }
        //尿素液位异常事件进行中
        OuterEventData eventData = drivingData.getEventData(eventType);
        isCurUreaAbnormal = Math.abs(drivingData.getCommonData().getUreaLevel()/100-Optional.ofNullable(var.getLast_level()).orElse(0.00)/100) >levelThreshold ;
        boolean isIn120 =drivingData.getCommonData().getGpsTime()-var.getAbnormal_time() <120000;
        if(null!=eventData && isCurUreaAbnormal && isIn120) {
            if (drivingData.getCommonData().getLastGpsTime() == var.getAbnormal_time()){
                var.setNext_level(drivingData.getCommonData().getUreaLevel());
                //ExtendField06 存放上一个点异常液位
                eventData.setExtendField06(Optional.ofNullable(var.getNext_level()).orElse(0.00));
            }


        }else if(null!=eventData && !isCurUreaAbnormal&& isIn120 ){//事件结束，清除正在缓冲的事件
            Optional.ofNullable(eventData).ifPresent(e ->{
                drivingData.removeEventData(e.getEvent());
            });
        }
        else if(null!=eventData && isCurUreaAbnormal&& !isIn120){
         //事件正常结束
         endEventData(var);
        }else{//事件结束，清除正在缓冲的事件
            Optional.ofNullable(eventData).ifPresent(e ->{
                drivingData.removeEventData(e.getEvent());
            });
        }
        logger.debug("{}算法结束...", arithmeticName);
    }

    @Override
    public void collect(OuterStatisticData statisticDataOut) {
        VarUreaLevel varUreaLevel = super.getObj();

    }


    private void endEventData(VarUreaLevel var){
        endEventData(eventType, eventData -> {
        var.addNumber(1);
        var.addMileage( Optional.ofNullable(eventData.getExtendField05()).orElse(0.0));
        var.addDuration( Optional.ofNullable(eventData.getDuration()).orElse(0L).intValue());
    });
}
}
